package com.aim.analysis.records;

import com.aim.util.HashMapOfList;
import com.aim.util.Histogram;
import com.aim.util.ListUtil;
import com.aim.util.Pair;

import java.util.List;
import java.util.TreeSet;

/**
 * User: Avraham Shvartzon
 * Date: 6/26/14
 */
public class PerformanceProcess {

    private static final int allGameDuration = 10 * 60 * 1000; // 10 minutes
    private static final int[] gamesStartTime = {0, 2 * 60 * 1000, (2+4) * 60 * 1000};
    private static final int numOfBuckets = 10 * 60; // 10 minutes


    public static double[] netScorePerSecond(Hit hit){
      Histogram h = new Histogram(0, allGameDuration, numOfBuckets);

        for (int i = 0; i < hit.gameList.size(); i++) {
            Game game = hit.gameList.get(i);
            int gameStartTime = gamesStartTime[i];

            for (long collisionTime : game.collisionTimes) {
                h.addValue(gameStartTime + collisionTime, -Scenario.instance().collisionCost);
            }

            for (long shutdownTime : game.shutdownTimes) {
                h.addValue(gameStartTime + shutdownTime, Scenario.instance().shutDownScore);
            }

            for (GameRecord record : game.getRecords()) {
                int recordStartTime = record.time + gameStartTime;
                if (record.recordType == RecordType.fuelFill){
                    h.addValue(recordStartTime, -(Scenario.instance().maxFuelInventory - record.fuelLevel)/1000);
                }
            }


        }
        return h.getBuckets();
    }

    public static double[] getScoreOnTime(Hit hit){
        Histogram h = new Histogram(0, allGameDuration, numOfBuckets);

        for (int i = 0; i < hit.gameList.size(); i++) {
            Game game = hit.gameList.get(i);
            int gameStartTime = gamesStartTime[i];

            for (long collisionTime : game.collisionTimes) {
                h.addValue(gameStartTime + collisionTime, -Scenario.instance().collisionCost);
            }

            for (long shutdownTime : game.shutdownTimes) {
                h.addValue(gameStartTime + shutdownTime, Scenario.instance().shutDownScore);
            }

            for (GameRecord record : game.getRecords()) {
                int recordStartTime = record.time + gameStartTime;
                switch (record.recordType){
                    case maintenaneAction:
                        h.addValue(recordStartTime, -Scenario.instance().maintenanceCost); break;
                    case repairAction:
                        switch (record.mechanicalCondition){
                            case M1: h.addValue(recordStartTime, -Scenario.instance().minorCost); break;
                            case M2: h.addValue(recordStartTime, -Scenario.instance().moderateCost); break;
                            case M3: h.addValue(recordStartTime, -Scenario.instance().severeCost); break;
                        }
                        break;
                    case fuelFill:
                        h.addValue(recordStartTime, -(Scenario.instance().maxFuelInventory - record.fuelLevel)/1000); break;
                    case fuelFillBySpaceship:
                        h.addValue(recordStartTime, -Scenario.instance().REFUEL_BY_SPACESHIP_COST); break;
                }
            }


        }

        return h.getAccumulative();
    }

    private static String printAverageNetScore(int threshold, double[] scoreOnTime, double[] netScoreOnTime){
        HashMapOfList<Boolean, Double> counter = new HashMapOfList<Boolean, Double>();
        for (int i = 0; i < scoreOnTime.length; i++) {
            counter.put(scoreOnTime[i] > threshold, netScoreOnTime[i]);
        }
        List<Double> beforeList = counter.get(false);
        double beforePercent = 1d * beforeList.size()/scoreOnTime.length;
        List<Double> afterList = counter.get(true);
        double afterListMean = afterList == null ? 0 : ListUtil.mean(afterList);
        return beforePercent + "\t" + ListUtil.mean(beforeList) + "\t" + (1-beforePercent) + "\t" + afterListMean;
    }

    public static void main(String[] args) {
        List<Hit> hits = Hit.getHits("20140616", "20140619");
        for (Hit hit : hits) {
            double[] scoreOnTime = getScoreOnTime(hit);
            double[] netScore = netScorePerSecond(hit);
            String report = printAverageNetScore(6000, scoreOnTime, netScore);
            System.out.println(hit.assignmentId + "\t" + hit.totalScores() + "\t" + report);
        }





    }
}
